﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using System.Diagnostics;

namespace TomAndJerry
{
    public static class InputManager
    {
        #region Action Enumeration


        /// <summary>
        /// The actions that are possible within the game.
        /// </summary>
        public enum Action
        {
            SoundEnable,
            SoundDisable,
            MusicEnable,
            MusicDisable,
            Instruction,
            Play,
            ArowLeft,
            BackHome,
            ArowRight,
            NextSkip,
            TestBridge,
            Walk,
            BackLevel,
            Quite,
            YesQuite,
            NoQuite,
            Retry,
            Help,
            NextLevel,
            DropBridge,
            DropItem,
            Exit,
        }


        /// <summary>
        /// Readable names of each action.
        /// </summary>
        private static readonly string[] actionNames = 
            {
                "Sound Enable",
                "Sound Disable",
                "Music Enable",
                "Music Disable",
                "Instruction",
                "Play",
                "Arow Left",
                "Back Home",
                "Arow Right",
                "Next Skip",
                "Test Bridge",
                "Walk",
                "Back Level",
                "Quite",
                "Yes Quite",
                "No Quite",
                "Retry",
                "Help",
                "Next Level",
                "Drop Bridge",
                "Drop Item",
                "Exit",
            };

        /// <summary>
        /// Returns the readable name of the given action.
        /// </summary>
        public static string GetActionName(Action action)
        {
            int index = (int)action;

            if ((index < 0) || (index > actionNames.Length))
            {
                throw new ArgumentException("action");
            }

            return actionNames[index];
        }


        #endregion


        #region Support Types


        /// <summary>
        /// GamePad controls expressed as one type, unified with button semantics.
        /// </summary>
        public enum GamePadButtons
        {
            Start,
            Back,
            A,
            B,
            X,
            Y,
            Up,
            Down,
            Left,
            Right,
            LeftShoulder,
            RightShoulder,
            LeftTrigger,
            RightTrigger,
        }


        /// <summary>
        /// A combination of gamepad and keyboard keys mapped to a particular action.
        /// </summary>
        public class ActionMap
        {
            /// <summary>
            /// List of GamePad controls to be mapped to a given action.
            /// </summary>
            public List<GamePadButtons> gamePadButtons = new List<GamePadButtons>();


            /// <summary>
            /// List of Keyboard controls to be mapped to a given action.
            /// </summary>
            public List<Keys> keyboardKeys = new List<Keys>();


            public WindowsPhoneGesture PhoneInput = new WindowsPhoneGesture();
        }

        public class WindowsPhoneGesture
        {
            public GestureType Type { get; set; }
            public GestureDirection Direction { get; set; }

            public bool IsBackGesture { get; set; }
            public bool IsStartGesture { get; set; }

            public WindowsPhoneGesture()
            {
                Type = GestureType.None;
                Direction = GestureDirection.None;
            }

        }

        #endregion


        #region Constants


        /// <summary>
        /// The value of an analog control that reads as a "pressed button".
        /// </summary>
        const float analogLimit = 0.5f;


        #endregion


        #region Keyboard Data


        /// <summary>
        /// The state of the keyboard as of the last update.
        /// </summary>
        private static KeyboardState currentKeyboardState;

        /// <summary>
        /// The state of the keyboard as of the last update.
        /// </summary>
        public static KeyboardState CurrentKeyboardState
        {
            get { return currentKeyboardState; }
        }


        /// <summary>
        /// The state of the keyboard as of the previous update.
        /// </summary>
        private static KeyboardState previousKeyboardState;


        /// <summary>
        /// Check if a key is pressed.
        /// </summary>
        public static bool IsKeyPressed(Keys key)
        {
            return currentKeyboardState.IsKeyDown(key);
        }


        /// <summary>
        /// Check if a key was just pressed in the most recent update.
        /// </summary>
        public static bool IsKeyTriggered(Keys key)
        {
            return (currentKeyboardState.IsKeyDown(key)) &&
                (!previousKeyboardState.IsKeyDown(key));
        }


        #endregion


        #region GamePad Data


        /// <summary>
        /// The state of the gamepad as of the last update.
        /// </summary>
        private static GamePadState currentGamePadState;

        /// <summary>
        /// The state of the gamepad as of the last update.
        /// </summary>
        public static GamePadState CurrentGamePadState
        {
            get { return currentGamePadState; }
        }


        /// <summary>
        /// The state of the gamepad as of the previous update.
        /// </summary>
        private static GamePadState previousGamePadState;


        #region GamePadButton Pressed Queries


        /// <summary>
        /// Check if the gamepad's Start button is pressed.
        /// </summary>
        public static bool IsGamePadStartPressed()
        {
            return (currentGamePadState.Buttons.Start == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if the gamepad's Back button is pressed.
        /// </summary>
        public static bool IsGamePadBackPressed()
        {
            return (currentGamePadState.Buttons.Back == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if the gamepad's A button is pressed.
        /// </summary>
        public static bool IsGamePadAPressed()
        {
            return (currentGamePadState.Buttons.A == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if the gamepad's B button is pressed.
        /// </summary>
        public static bool IsGamePadBPressed()
        {
            return (currentGamePadState.Buttons.B == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if the gamepad's X button is pressed.
        /// </summary>
        public static bool IsGamePadXPressed()
        {
            return (currentGamePadState.Buttons.X == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if the gamepad's Y button is pressed.
        /// </summary>
        public static bool IsGamePadYPressed()
        {
            return (currentGamePadState.Buttons.Y == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if the gamepad's LeftShoulder button is pressed.
        /// </summary>
        public static bool IsGamePadLeftShoulderPressed()
        {
            return (currentGamePadState.Buttons.LeftShoulder == ButtonState.Pressed);
        }


        /// <summary>
        /// <summary>
        /// Check if the gamepad's RightShoulder button is pressed.
        /// </summary>
        public static bool IsGamePadRightShoulderPressed()
        {
            return (currentGamePadState.Buttons.RightShoulder == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if Up on the gamepad's directional pad is pressed.
        /// </summary>
        public static bool IsGamePadDPadUpPressed()
        {
            return (currentGamePadState.DPad.Up == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if Down on the gamepad's directional pad is pressed.
        /// </summary>
        public static bool IsGamePadDPadDownPressed()
        {
            return (currentGamePadState.DPad.Down == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if Left on the gamepad's directional pad is pressed.
        /// </summary>
        public static bool IsGamePadDPadLeftPressed()
        {
            return (currentGamePadState.DPad.Left == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if Right on the gamepad's directional pad is pressed.
        /// </summary>
        public static bool IsGamePadDPadRightPressed()
        {
            return (currentGamePadState.DPad.Right == ButtonState.Pressed);
        }


        /// <summary>
        /// Check if the gamepad's left trigger is pressed.
        /// </summary>
        public static bool IsGamePadLeftTriggerPressed()
        {
            return (currentGamePadState.Triggers.Left > analogLimit);
        }


        /// <summary>
        /// Check if the gamepad's right trigger is pressed.
        /// </summary>
        public static bool IsGamePadRightTriggerPressed()
        {
            return (currentGamePadState.Triggers.Right > analogLimit);
        }


        /// <summary>
        /// Check if Up on the gamepad's left analog stick is pressed.
        /// </summary>
        public static bool IsGamePadLeftStickUpPressed()
        {
            return (currentGamePadState.ThumbSticks.Left.Y > analogLimit);
        }


        /// <summary>
        /// Check if Down on the gamepad's left analog stick is pressed.
        /// </summary>
        public static bool IsGamePadLeftStickDownPressed()
        {
            return (-1f * currentGamePadState.ThumbSticks.Left.Y > analogLimit);
        }


        /// <summary>
        /// Check if Left on the gamepad's left analog stick is pressed.
        /// </summary>
        public static bool IsGamePadLeftStickLeftPressed()
        {
            return (-1f * currentGamePadState.ThumbSticks.Left.X > analogLimit);
        }


        /// <summary>
        /// Check if Right on the gamepad's left analog stick is pressed.
        /// </summary>
        public static bool IsGamePadLeftStickRightPressed()
        {
            return (currentGamePadState.ThumbSticks.Left.X > analogLimit);
        }


        /// <summary>
        /// Check if the GamePadKey value specified is pressed.
        /// </summary>
        private static bool IsGamePadButtonPressed(GamePadButtons gamePadKey)
        {
            switch (gamePadKey)
            {
                case GamePadButtons.Start:
                    return IsGamePadStartPressed();

                case GamePadButtons.Back:
                    return IsGamePadBackPressed();

                case GamePadButtons.A:
                    return IsGamePadAPressed();

                case GamePadButtons.B:
                    return IsGamePadBPressed();

                case GamePadButtons.X:
                    return IsGamePadXPressed();

                case GamePadButtons.Y:
                    return IsGamePadYPressed();

                case GamePadButtons.LeftShoulder:
                    return IsGamePadLeftShoulderPressed();

                case GamePadButtons.RightShoulder:
                    return IsGamePadRightShoulderPressed();

                case GamePadButtons.LeftTrigger:
                    return IsGamePadLeftTriggerPressed();

                case GamePadButtons.RightTrigger:
                    return IsGamePadRightTriggerPressed();

                case GamePadButtons.Up:
                    return IsGamePadDPadUpPressed() ||
                        IsGamePadLeftStickUpPressed();

                case GamePadButtons.Down:
                    return IsGamePadDPadDownPressed() ||
                        IsGamePadLeftStickDownPressed();

                case GamePadButtons.Left:
                    return IsGamePadDPadLeftPressed() ||
                        IsGamePadLeftStickLeftPressed();

                case GamePadButtons.Right:
                    return IsGamePadDPadRightPressed() ||
                        IsGamePadLeftStickRightPressed();
            }

            return false;
        }


        #endregion


        #region GamePadButton Triggered Queries


        /// <summary>
        /// Check if the gamepad's Start button was just pressed.
        /// </summary>
        public static bool IsGamePadStartTriggered()
        {
            return ((currentGamePadState.Buttons.Start == ButtonState.Pressed) &&
              (previousGamePadState.Buttons.Start == ButtonState.Released));
        }


        /// <summary>
        /// Check if the gamepad's Back button was just pressed.
        /// </summary>
        public static bool IsGamePadBackTriggered()
        {
            return ((currentGamePadState.Buttons.Back == ButtonState.Pressed) &&
              (previousGamePadState.Buttons.Back == ButtonState.Released));
        }


        /// <summary>
        /// Check if the gamepad's A button was just pressed.
        /// </summary>
        public static bool IsGamePadATriggered()
        {
            return ((currentGamePadState.Buttons.A == ButtonState.Pressed) &&
              (previousGamePadState.Buttons.A == ButtonState.Released));
        }


        /// <summary>
        /// Check if the gamepad's B button was just pressed.
        /// </summary>
        public static bool IsGamePadBTriggered()
        {
            return ((currentGamePadState.Buttons.B == ButtonState.Pressed) &&
              (previousGamePadState.Buttons.B == ButtonState.Released));
        }


        /// <summary>
        /// Check if the gamepad's X button was just pressed.
        /// </summary>
        public static bool IsGamePadXTriggered()
        {
            return ((currentGamePadState.Buttons.X == ButtonState.Pressed) &&
              (previousGamePadState.Buttons.X == ButtonState.Released));
        }


        /// <summary>
        /// Check if the gamepad's Y button was just pressed.
        /// </summary>
        public static bool IsGamePadYTriggered()
        {
            return ((currentGamePadState.Buttons.Y == ButtonState.Pressed) &&
              (previousGamePadState.Buttons.Y == ButtonState.Released));
        }


        /// <summary>
        /// Check if the gamepad's LeftShoulder button was just pressed.
        /// </summary>
        public static bool IsGamePadLeftShoulderTriggered()
        {
            return (
                (currentGamePadState.Buttons.LeftShoulder == ButtonState.Pressed) &&
                (previousGamePadState.Buttons.LeftShoulder == ButtonState.Released));
        }


        /// <summary>
        /// Check if the gamepad's RightShoulder button was just pressed.
        /// </summary>
        public static bool IsGamePadRightShoulderTriggered()
        {
            return (
                (currentGamePadState.Buttons.RightShoulder == ButtonState.Pressed) &&
                (previousGamePadState.Buttons.RightShoulder == ButtonState.Released));
        }


        /// <summary>
        /// Check if Up on the gamepad's directional pad was just pressed.
        /// </summary>
        public static bool IsGamePadDPadUpTriggered()
        {
            return ((currentGamePadState.DPad.Up == ButtonState.Pressed) &&
              (previousGamePadState.DPad.Up == ButtonState.Released));
        }


        /// <summary>
        /// Check if Down on the gamepad's directional pad was just pressed.
        /// </summary>
        public static bool IsGamePadDPadDownTriggered()
        {
            return ((currentGamePadState.DPad.Down == ButtonState.Pressed) &&
              (previousGamePadState.DPad.Down == ButtonState.Released));
        }


        /// <summary>
        /// Check if Left on the gamepad's directional pad was just pressed.
        /// </summary>
        public static bool IsGamePadDPadLeftTriggered()
        {
            return ((currentGamePadState.DPad.Left == ButtonState.Pressed) &&
              (previousGamePadState.DPad.Left == ButtonState.Released));
        }


        /// <summary>
        /// Check if Right on the gamepad's directional pad was just pressed.
        /// </summary>
        public static bool IsGamePadDPadRightTriggered()
        {
            return ((currentGamePadState.DPad.Right == ButtonState.Pressed) &&
              (previousGamePadState.DPad.Right == ButtonState.Released));
        }


        /// <summary>
        /// Check if the gamepad's left trigger was just pressed.
        /// </summary>
        public static bool IsGamePadLeftTriggerTriggered()
        {
            return ((currentGamePadState.Triggers.Left > analogLimit) &&
                (previousGamePadState.Triggers.Left < analogLimit));
        }


        /// <summary>
        /// Check if the gamepad's right trigger was just pressed.
        /// </summary>
        public static bool IsGamePadRightTriggerTriggered()
        {
            return ((currentGamePadState.Triggers.Right > analogLimit) &&
                (previousGamePadState.Triggers.Right < analogLimit));
        }


        /// <summary>
        /// Check if Up on the gamepad's left analog stick was just pressed.
        /// </summary>
        public static bool IsGamePadLeftStickUpTriggered()
        {
            return ((currentGamePadState.ThumbSticks.Left.Y > analogLimit) &&
                (previousGamePadState.ThumbSticks.Left.Y < analogLimit));
        }


        /// <summary>
        /// Check if Down on the gamepad's left analog stick was just pressed.
        /// </summary>
        public static bool IsGamePadLeftStickDownTriggered()
        {
            return ((-1f * currentGamePadState.ThumbSticks.Left.Y > analogLimit) &&
                (-1f * previousGamePadState.ThumbSticks.Left.Y < analogLimit));
        }


        /// <summary>
        /// Check if Left on the gamepad's left analog stick was just pressed.
        /// </summary>
        public static bool IsGamePadLeftStickLeftTriggered()
        {
            return ((-1f * currentGamePadState.ThumbSticks.Left.X > analogLimit) &&
                (-1f * previousGamePadState.ThumbSticks.Left.X < analogLimit));
        }


        /// <summary>
        /// Check if Right on the gamepad's left analog stick was just pressed.
        /// </summary>
        public static bool IsGamePadLeftStickRightTriggered()
        {
            return ((currentGamePadState.ThumbSticks.Left.X > analogLimit) &&
                (previousGamePadState.ThumbSticks.Left.X < analogLimit));
        }


        /// <summary>
        /// Check if the GamePadKey value specified was pressed this frame.
        /// </summary>
        private static bool IsGamePadButtonTriggered(GamePadButtons gamePadKey)
        {
            switch (gamePadKey)
            {
                case GamePadButtons.Start:
                    return IsGamePadStartTriggered();

                case GamePadButtons.Back:
                    return IsGamePadBackTriggered();

                case GamePadButtons.A:
                    return IsGamePadATriggered();

                case GamePadButtons.B:
                    return IsGamePadBTriggered();

                case GamePadButtons.X:
                    return IsGamePadXTriggered();

                case GamePadButtons.Y:
                    return IsGamePadYTriggered();

                case GamePadButtons.LeftShoulder:
                    return IsGamePadLeftShoulderTriggered();

                case GamePadButtons.RightShoulder:
                    return IsGamePadRightShoulderTriggered();

                case GamePadButtons.LeftTrigger:
                    return IsGamePadLeftTriggerTriggered();

                case GamePadButtons.RightTrigger:
                    return IsGamePadRightTriggerTriggered();

                case GamePadButtons.Up:
                    return IsGamePadDPadUpTriggered() ||
                        IsGamePadLeftStickUpTriggered();

                case GamePadButtons.Down:
                    return IsGamePadDPadDownTriggered() ||
                        IsGamePadLeftStickDownTriggered();

                case GamePadButtons.Left:
                    return IsGamePadDPadLeftTriggered() ||
                        IsGamePadLeftStickLeftTriggered();

                case GamePadButtons.Right:
                    return IsGamePadDPadRightTriggered() ||
                        IsGamePadLeftStickRightTriggered();
            }

            return false;
        }


        #endregion


        #endregion


        #region Touch Data

        /// <summary>
        /// The state of the touch as of the last update.
        /// </summary>
        private static TouchCollection currentTouchState;

        /// <summary>
        /// The state of the touch as of the last update.
        /// </summary>
        public static TouchCollection CurrentTouchState
        {
            get { return currentTouchState; }
        }

        /// <summary>
        /// The state of the touch as of the previous update.
        /// </summary>
        private static TouchCollection previousTouchState;

        public static List<GestureSample> Gestures { get; set; }

        private static bool IsBackPressed()
        {
            //return GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed;
            return false;
        }

        private static bool IsStartPressed()
        {
            //return GamePad.GetState(PlayerIndex.One).Buttons.Start == ButtonState.Pressed;
            return false;
        }



        #endregion


        #region Action Mapping


        /// <summary>
        /// The action mappings for the game.
        /// </summary>
        private static ActionMap[] actionMaps;


        public static ActionMap[] ActionMaps
        {
            get { return actionMaps; }
        }


        /// <summary>
        /// Reset the action maps to their default values.
        /// </summary>
        private static void ResetActionMaps()
        {
            actionMaps = new ActionMap[22];

            actionMaps[(int)Action.SoundEnable] = new ActionMap();
            actionMaps[(int)Action.SoundEnable].keyboardKeys.Add(
                Keys.Tab);
            actionMaps[(int)Action.SoundDisable] = new ActionMap();
            actionMaps[(int)Action.SoundDisable].gamePadButtons.Add(
                GamePadButtons.Start);
            actionMaps[(int)Action.SoundDisable].PhoneInput.IsBackGesture = true;

            actionMaps[(int)Action.Instruction] = new ActionMap();
            actionMaps[(int)Action.Instruction].keyboardKeys.Add(
                Keys.Enter);
            actionMaps[(int)Action.Instruction].gamePadButtons.Add(
                GamePadButtons.A);

            actionMaps[(int)Action.ArowLeft] = new ActionMap();
            actionMaps[(int)Action.ArowLeft].keyboardKeys.Add(
                Keys.Escape);
            actionMaps[(int)Action.ArowLeft].gamePadButtons.Add(
                GamePadButtons.B);
            actionMaps[(int)Action.ArowLeft].PhoneInput.IsBackGesture = true;

            actionMaps[(int)Action.Play] = new ActionMap();
            actionMaps[(int)Action.Play].keyboardKeys.Add(
                Keys.Space);
            actionMaps[(int)Action.Play].gamePadButtons.Add(
                GamePadButtons.Y);

            actionMaps[(int)Action.Quite] = new ActionMap();
            actionMaps[(int)Action.Quite].keyboardKeys.Add(
                Keys.Escape);
            actionMaps[(int)Action.Quite].gamePadButtons.Add(
                GamePadButtons.Back);
            actionMaps[(int)Action.Quite].PhoneInput.IsStartGesture = true;

            actionMaps[(int)Action.NextLevel] = new ActionMap();
            actionMaps[(int)Action.NextLevel].keyboardKeys.Add(
                Keys.LeftControl);
            actionMaps[(int)Action.NextLevel].gamePadButtons.Add(
                GamePadButtons.Y);

            actionMaps[(int)Action.NextSkip] = new ActionMap();
            actionMaps[(int)Action.NextSkip].keyboardKeys.Add(
                Keys.D);
            actionMaps[(int)Action.NextSkip].gamePadButtons.Add(
                GamePadButtons.X);

            actionMaps[(int)Action.BackLevel] = new ActionMap();
            actionMaps[(int)Action.BackLevel].keyboardKeys.Add(
                Keys.Up);
            actionMaps[(int)Action.BackLevel].gamePadButtons.Add(
                GamePadButtons.Up);
            actionMaps[(int)Action.BackLevel].PhoneInput.Direction = GestureDirection.Up;
            actionMaps[(int)Action.BackLevel].PhoneInput.Type = GestureType.VerticalDrag;

            actionMaps[(int)Action.DropBridge] = new ActionMap();
            actionMaps[(int)Action.DropBridge].keyboardKeys.Add(
                Keys.Down);
            actionMaps[(int)Action.DropBridge].gamePadButtons.Add(
                GamePadButtons.Down);
            actionMaps[(int)Action.DropBridge].PhoneInput.Direction = GestureDirection.Down;
            actionMaps[(int)Action.DropBridge].PhoneInput.Type = GestureType.VerticalDrag;

            actionMaps[(int)Action.DropItem] = new ActionMap();
            actionMaps[(int)Action.DropItem].keyboardKeys.Add(
                Keys.Left);
            actionMaps[(int)Action.DropItem].gamePadButtons.Add(
                GamePadButtons.Left);
            actionMaps[(int)Action.DropItem].PhoneInput.Direction = GestureDirection.Left;
            actionMaps[(int)Action.DropItem].PhoneInput.Type = GestureType.HorizontalDrag;

            actionMaps[(int)Action.DropItem] = new ActionMap();
            actionMaps[(int)Action.DropItem].keyboardKeys.Add(
                Keys.Right);
            actionMaps[(int)Action.Exit] = new ActionMap();
            actionMaps[(int)Action.Exit].gamePadButtons.Add(
                GamePadButtons.Right);
            actionMaps[(int)Action.Exit].PhoneInput.Direction = GestureDirection.Right;
            actionMaps[(int)Action.Exit].PhoneInput.Type = GestureType.HorizontalDrag;

            actionMaps[(int)Action.Help] = new ActionMap();
            actionMaps[(int)Action.Help].keyboardKeys.Add(
                Keys.Up);
            actionMaps[(int)Action.Help].gamePadButtons.Add(
                GamePadButtons.Up);
            actionMaps[(int)Action.Help].PhoneInput.Direction = GestureDirection.Up;
            actionMaps[(int)Action.Help].PhoneInput.Type = GestureType.VerticalDrag;

            actionMaps[(int)Action.TestBridge] = new ActionMap();
            actionMaps[(int)Action.TestBridge].keyboardKeys.Add(
                Keys.Down);
            actionMaps[(int)Action.TestBridge].gamePadButtons.Add(
                GamePadButtons.Down);
            actionMaps[(int)Action.TestBridge].PhoneInput.Direction = GestureDirection.Down;
            actionMaps[(int)Action.TestBridge].PhoneInput.Type = GestureType.VerticalDrag;

            actionMaps[(int)Action.Walk] = new ActionMap();
            actionMaps[(int)Action.Walk].keyboardKeys.Add(
                Keys.Left);
            actionMaps[(int)Action.Walk].gamePadButtons.Add(
                GamePadButtons.Left);
            actionMaps[(int)Action.Walk].PhoneInput.Direction = GestureDirection.Left;
            actionMaps[(int)Action.Walk].PhoneInput.Type = GestureType.HorizontalDrag;

            actionMaps[(int)Action.Retry] = new ActionMap();
            actionMaps[(int)Action.Retry].keyboardKeys.Add(
                Keys.Right);
            actionMaps[(int)Action.Retry].gamePadButtons.Add(
                GamePadButtons.Right);
            actionMaps[(int)Action.Retry].PhoneInput.Direction = GestureDirection.Right;
            actionMaps[(int)Action.Retry].PhoneInput.Type = GestureType.HorizontalDrag;

            actionMaps[(int)Action.YesQuite] = new ActionMap();
            actionMaps[(int)Action.YesQuite].keyboardKeys.Add(
                Keys.LeftShift);
            actionMaps[(int)Action.YesQuite].gamePadButtons.Add(
                GamePadButtons.LeftTrigger);
            actionMaps[(int)Action.YesQuite].PhoneInput.Direction = GestureDirection.Left;
            actionMaps[(int)Action.YesQuite].PhoneInput.Type = GestureType.Flick;

            actionMaps[(int)Action.NoQuite] = new ActionMap();
            actionMaps[(int)Action.NoQuite].keyboardKeys.Add(
                Keys.RightShift);
            actionMaps[(int)Action.NoQuite].gamePadButtons.Add(
                GamePadButtons.RightTrigger);
            actionMaps[(int)Action.NoQuite].PhoneInput.Direction = GestureDirection.Right;
            actionMaps[(int)Action.NoQuite].PhoneInput.Type = GestureType.Flick;
        }


        /// <summary>
        /// Check if an action has been pressed.
        /// </summary>
        public static bool IsActionPressed(Action action)
        {
            return IsActionMapPressed(actionMaps[(int)action]);
        }

        /// <summary>
        /// Check if an action was just performed in the most recent update.
        /// </summary>
        public static bool IsActionTriggered(Action action)
        {
            return IsActionMapTriggered(actionMaps[(int)action]);
        }



        /// <summary>
        /// Check if an action map has been pressed.
        /// </summary>
        private static bool IsActionMapPressed(ActionMap actionMap)
        {
            bool result = false;
            for (int i = 0; i < actionMap.keyboardKeys.Count; i++)
            {
                if (IsKeyPressed(actionMap.keyboardKeys[i]))
                {
                    result = true;
                }
            }
            if (currentGamePadState.IsConnected)
            {
                for (int i = 0; i < actionMap.gamePadButtons.Count; i++)
                {
                    if (IsGamePadButtonPressed(actionMap.gamePadButtons[i]))
                    {
                        result = true;
                    }
                }
            }


            // Handle Windows Phone gestures
            if (!result)
            {
                if (actionMap.PhoneInput.IsStartGesture)
                {
                    result = IsStartPressed();
                }
                else if (actionMap.PhoneInput.IsBackGesture)
                {
                    result = IsBackPressed();
                }
                else
                {
                    if (Gestures.Count > 0)
                    {
                        GestureSample gesture = Gestures[Gestures.Count - 1];
                        if (gesture.GestureType == actionMap.PhoneInput.Type)
                        {
                            if (gesture.GetDirection() == actionMap.PhoneInput.Direction
                                && gesture.GetDirection() == actionMap.PhoneInput.Direction)
                            {
                                InputManager.Gestures.Remove(gesture);
                                result = true;
                            }
                        }
                    }
                }
            }
            return result;
        }

 

        /// <summary>
        /// Check if an action map has been triggered this frame.
        /// </summary>
        private static bool IsActionMapTriggered(ActionMap actionMap)
        {
            bool result = false;
            for (int i = 0; i < actionMap.keyboardKeys.Count; i++)
            {
                if (IsKeyTriggered(actionMap.keyboardKeys[i]))
                {
                    result = true;
                }
            }
            if (currentGamePadState.IsConnected)
            {
                for (int i = 0; i < actionMap.gamePadButtons.Count; i++)
                {
                    if (IsGamePadButtonTriggered(actionMap.gamePadButtons[i]))
                    {
                        result = true;
                    }
                }
            }

            // Handle Windows Phone gestures
            if (!result)
            {
                if (actionMap.PhoneInput.IsStartGesture)
                {
                    result = IsStartPressed();
                }
                else if (actionMap.PhoneInput.IsBackGesture)
                {
                    result = IsBackPressed();
                }
                else
                {
                    if (Gestures.Count > 0)
                    {
                        GestureSample gesture = Gestures[Gestures.Count - 1];
                        if (gesture.GestureType == actionMap.PhoneInput.Type
                            && gesture.GetDirection() == actionMap.PhoneInput.Direction)
                        {
                            InputManager.Gestures.Remove(gesture);
                            result = true;
                        }
                    }
                }
            }

            return result;
        }


        #endregion


        #region Initialization


        /// <summary>
        /// Initializes the default control keys for all actions.
        /// </summary>
        public static void Initialize()
        {
            TouchPanel.EnabledGestures = GestureType.Tap |GestureType.DragComplete|GestureType.Hold|GestureType.FreeDrag|GestureType.Hold|GestureType.Pinch;
            ResetActionMaps();
            Gestures = new List<GestureSample>();
        }


        #endregion


        #region Updating


        /// <summary>
        /// Updates the keyboard and gamepad control states.
        /// </summary>
        public static void Update()
        {
            Gestures.Clear();

            // update the keyboard state
            previousKeyboardState = currentKeyboardState;
            currentKeyboardState = Keyboard.GetState();

            // update the gamepad state
           // previousGamePadState = currentGamePadState;
           // currentGamePadState = GamePad.GetState(PlayerIndex.One);

            // Update the touch state
            previousTouchState = currentTouchState;
            currentTouchState = TouchPanel.GetState();


            while (TouchPanel.IsGestureAvailable)
            {
                var gesture = TouchPanel.ReadGesture();
                Gestures.Add(gesture);
            }
        }


        #endregion


        public static bool IsButtonClicked(Rectangle[] positions)
        {
            foreach (var gesture in Gestures)
            {
                if (gesture.GestureType == GestureType.DragComplete)
                    Debug.WriteLine("com================ drag");
                else if (gesture.GestureType == GestureType.FreeDrag)
                    Debug.WriteLine("free drag");
                else if (gesture.GestureType == GestureType.HorizontalDrag)
                {
                    if (gesture.Delta.Y > 0)
                        Debug.WriteLine("hoho");
                    Debug.WriteLine("horizontal drag");
                }
                else if (gesture.GestureType == GestureType.VerticalDrag)
                    Debug.WriteLine("vert drag");
                else if (gesture.GestureType == GestureType.DragComplete)
                    Debug.WriteLine("complete drag");
                else if (gesture.GestureType == GestureType.Flick)
                    Debug.WriteLine("flick drag"); 
                Debug.WriteLine("Have Click " + positions.Length);
                foreach (Rectangle rect in positions)
                {
                  //  Debug.WriteLine("noi click: " + gesture.Position.X + "---" + gesture.Position.Y);
                 //   Debug.WriteLine("rectangle: x= " + rect.X + " y= "+rect.Y + "---w= " + rect.Width +" h= "+ rect.Height);
                    if (rect.Contains((int)gesture.Position.X, (int)gesture.Position.Y))
                    {
                        Gestures.Remove(gesture);
                     //   Debug.WriteLine("Click");
                        return true;
                    }
                }
            }
            return false;
        }

        public static ItemSprite DrawTouchGesture(ItemSprite item)
        {
           
            foreach (var gesture in Gestures)
            {
                if (item.infor.Mode == 1 && gesture.GestureType == GestureType.DragComplete)
                {
                    item.infor.Mode = 2;
                    Debug.WriteLine("stop touch");
                }
                if (item.infor.Mode == 0 && gesture.GestureType == GestureType.FreeDrag)
                {
                    item.infor.Mode = 1;
                    item.infor.Pos1 = new Vector2(gesture.Position.X, gesture.Position.Y);
                }
                else if(item.infor.Mode == 2)
                {
                    return item;
                }
                if (gesture.GestureType == GestureType.Pinch)
                {
                    Debug.WriteLine("hoho");
                }
                float delta_x =gesture.Position.X - item.infor.Pos1.X;
                float delta_y = gesture.Position.Y - item.infor.Pos1.Y;
                //rotate = (Math.Abs(gesture.Position.X - pos.X)) / (Math.Abs(gesture.Position.Y - pos.Y));
                if (gesture.Position.X == 0 && gesture.Position.Y == 0) continue;
                item.infor.Angle = ArcTanAngle(delta_x, delta_y);                
                //Debug.WriteLine(info.Angle+"+++++++++++++++" + gesture.Position.X + "=="+ gesture.Position.Y);
                Vector2 vecto = new Vector2();
                vecto.X = (float) Math.Sqrt(Math.Pow((Math.Abs(gesture.Position.X - item.infor.Pos1.X)),2) + Math.Pow((Math.Abs(gesture.Position.Y - item.infor.Pos1.Y)),2))/item.itemTexture.Width;
                vecto.X += 0.1f;
                vecto.Y = 1;
                item.infor.Scale = vecto;
                item.infor.Pos2 = new Vector2(gesture.Position.X, gesture.Position.Y);
            }

            return item;
        }

        public static float ArcTanAngle(float X, float Y)
        {
            if (X == 0)
            {
                if (Y >= 0)
                    return (float)MathHelper.PiOver2;
                else
                    return (float)-MathHelper.PiOver2;
            }
            else if (X > 0)
                return (float)Math.Atan(Y / X);
            else if (X < 0)
            {
                if (Y > 0)
                    return (float)Math.Atan(Y / X) + MathHelper.Pi;
                else
                    return (float)Math.Atan(Y / X) - MathHelper.Pi;
            }
            else
                return 0;
        }

        public static bool IsButtonClicked(Rectangle position)
        {
            return IsButtonClicked(new Rectangle[] { position });
        }
    }
}
